﻿/*
 * PsTFS is a set of PowerShell commands to manage and use Team Foundation Server. PowerShell 
 * effectiveness is combined with the power of TFS API to maximizes TFS capabilities.
 * 
 * Creator : Suman Chakrabarti
 * Blog : http://blogs.msdn.com/sumanc
 * 
 */
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Management.Automation;
using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.VersionControl.Client;
using PsTFS.Objects;
using PsTFS.Objects.Methodes;

namespace PsTFS.Commandes.Get
{
    /// <summary>
    /// Permet de récupérer les fichiers entre un label et la dernière version
    /// </summary>
    [Cmdlet(VerbsCommon.Get, "AllChangesSinceLabel")]
    public class Get_AllChangesSinceLabel : PsCmdlet
    {
        /// <summary>
        /// Permet de lancer le processus
        /// </summary>
        /// <returns>L'ensemble des données entre deux éléments (LABEL, dDernière version)</returns>
        /// <exception cref="ArgumentException">Nom du serveur TFS non valide</exception>
        /// <exception cref="ArgumentException">Nom du label non valide</exception>
        /// <exception cref="ArgumentException">Nom du label non unique</exception>
        protected override void ProcessRecord()
        {
            VersionControlServer versionControl = Methode_Service.VCS();

            Console.WriteLine("Get-AllChangesSinceLabel called with parameters:\r\nPath={0}\r\nLabel={1}\r\nFolderPath={2}\r\n", Context.GetContext().Project, Label, FolderPath);
            
            VersionSpec currentVersion = VersionSpec.Latest;
            VersionControlLabel[] labels = versionControl.QueryLabels(Label, Context.GetContext().Project.Name, null, true);

            if (labels.Length == 0)
                WriteError(new ErrorRecord(new ArgumentException(string.Format("No labels exist in the path {0} with the name {1}", Context.GetContext().Project, this.Label)), "PsTFS", ErrorCategory.ObjectNotFound, Context.GetContext().Tfs));
            if (labels.Length > 1)
                WriteError(new ErrorRecord(new ArgumentException("More than one Label by the name: " + this.Label), "PsTFS", ErrorCategory.ObjectNotFound, Context.GetContext().Tfs));

            var ids = labels[0].Items.Select(item => item.ItemId);
            int latestChangesetID = versionControl.GetLatestChangesetId();
            var latestItems = versionControl.GetItems(ids.ToArray(), latestChangesetID);
            List<Item> changedItems = new List<Item>();

            foreach (Item item in labels[0].Items)
            {
                Item latestChgSetItem = latestItems.Single(i => i.ItemId == item.ItemId);
                if (latestChgSetItem.ChangesetId != item.ChangesetId)
                {
                    changedItems.Add(item);
                    Console.WriteLine("\r\nItem#: {0}\r\nChangeSetId: {1}\r\nPath: {2}", item.ItemId, latestChgSetItem.ChangesetId, item.ServerItem);
                }
            }
            Console.WriteLine();
            WriteObject(changedItems);

            if (!string.IsNullOrEmpty(FolderPath))
            {
                foreach (Item item in changedItems)
                {
                    string partialFileName = item.ServerItem.Replace('/', '\\').Remove(0, 1);
                    string filePath = System.IO.Path.Combine(FolderPath, partialFileName.Trim('\\'));
                    string directory = Directory.GetDirectoryRoot(filePath);
                    WriteVerbose("FilePath: " + filePath);

                    if (!Directory.Exists(directory))
                        Directory.CreateDirectory(directory);

                    item.DownloadFile(filePath);
                    Console.WriteLine("Write file: {0}", filePath);
                }
            }

            base.ProcessRecord();
        }

        /// <summary>
        /// Fin du processus
        /// </summary>
        protected override void EndProcessing()
        {
            Log.AddLog(null, "Get-AllChangesSinceLabel end");
            base.EndProcessing();
        }

        /// <summary>
        /// Object contenant Team Foundation Server
        /// </summary>
        /// <value>Serveur Team Foundation Server</value>
        /// <example>http://colmar:8080</example>
        [Parameter(Position = 0)]
        public TeamFoundationServer TFS
        {
            set { Context.GetContext().Tfs = value; }
        }

        /// <summary>
        /// Emplacement sur le serveur TFS
        /// </summary>
        /// <value>Chemin sur le serveur</value>
        /// <example>$\MonProjet\Dev</example>
        [Parameter(Position = 1)]
        public string Path
        {
            set { Context.GetContext().Project = Methode.GetProject(value); }
        }

        /// <summary>
        /// Label à récupérer
        /// </summary>
        /// <value>Nom du label</value>
        /// <example>MonLabel</example>
        [Parameter(Position = 2, Mandatory = true)]
        public string Label { get; set; }

        /// <summary>
        /// Emplacement en local pour la réupération des données
        /// </summary>
        /// <value>Chemin en local</value>
        /// <example>C:\Temp\Info\</example>
        [Parameter(Position = 3)]
        public string FolderPath { get; set; }
    }
}
